<?php

class ActivityController extends Controller
{
   
    private $_model;

    public $menu = array(
        array(
            'label' =>  '工作流活动',
        ),
        array(
            'label' =>  'MapRed活动',
            'icon'  =>  'list-alt',
            'url'   =>  array('/activity/index', 'type'=>0),
        ),
        array(
            'label' =>  'Hive活动',
            'icon'  =>  'search',
            'url'   =>  array('/activity/index', 'type'=>1),
        ),
        array(
            'label' =>  'Mysql活动',
            'icon'  =>  'hdd',
            'url'   =>  array('/activity/index', 'type'=>2),
        ),
        array(
            'label' =>  'Shell活动',
            'icon'  =>  'file',
            'url'   =>  array('/activity/index', 'type'=>3),
        ),
        array(
            'label' =>  'DataX活动',
            'icon'  =>  'random',
            'url'   =>  array('/activity/index', 'type'=>4),
        ),
        array(
            'label' =>  'Exec活动',
            'icon'  =>  'play-circle',
            'url'   =>  array('/activity/index', 'type'=>5),
        ),
    );
    
    /**
     * @return array action filters
     * 
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
        );
    }

	/**
	 * This is the default 'index' action that is invoked
	 * when an action is not explicitly requested by users.
	 */
	public function actionIndex()
	{
		// renders the view file 'protected/views/activity/index.php'
        $model=new Activity;
        if(isset($_GET['Activity'])) {
            $model->attributes=$_GET['Activity'];
        }

        $criteria = new CDbCriteria;
		
		if(isset($_GET['id'])) {
            $criteria->compare('activity_id', intval($_GET['id']));
        }
        
		if(isset($_GET['type'])) {
            $criteria->compare('activity_type', intval($_GET['type']));
        }
        $dataProvider = new CActiveDataProvider('Activity', array(
            'pagination'    =>  array(
                'pageSize'  =>  20,
            ),
            'criteria'  =>  $criteria,
        ));
        $this->render('index', array(
            'dataProvider'  => $dataProvider,
            'model'         => $model,
        ));       
    } 
    
	public function actionCreate()
    {
    	$model=new Activity;
    	$model->activity_type = $_GET['type'];
    	if(isset($_POST['Activity']))
    	{
    		$model->setAttributes($_POST['Activity'], false);
	    	if($model->activity_type != ActivityType::MapRed) {
	    		$status = $this->createActivity($model);
	        	if($status == false) {
	        		Yii::log("create activity[{$model->activity_name}] failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
	        	}
	           
	        }
	        else {
	        	$status = $this->createMapRedActivity($model);
	        	if($status == false) {
	        		Yii::log("create mapred activity[{$model->activity_name}] failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
	        	}
	        }
	        
    		if($model->save()) {
    			$this->redirect(array('index', 'type'=>$model->activity_type));
    		}
    		else {
    			Yii::log("save activity[{$model->activity_name}] to DB failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
    		}
    	}
    	
    	$this->render('create',array(
        	'model'=>$model,
            'type'=>$model->activity_type,
    	));
        
    }

    public function actionUpdate($id, $type)
    {
        $model=$this->loadModel();
        $programs = CJSON::decode($model->programs);
        if($type != ActivityType::MapRed) {
            $model->programs = $programs[0];
        }
        else {
            // parse programs
            if(count($programs) == 1) {
                $model->jar = $programs[0];
                $model->mapred_type = MapRedType::Native;
            }
            else {
                $model->map = $programs[0];
                $model->reduce = $programs[1];
                $model->mapred_type = MapRedType::Streaming;
            }			
            // parse params
            $model->params = CJSON::decode($model->params);
            $params = new ParamForm;
            $params->input_format = str_replace('-inputformat ', '', $model->params['inputformat']);
            $params->output_format = str_replace('-outputformat ', '', $model->params['outputformat']);
            $params->partitioner = str_replace('-partitioner ', '', $model->params['partitioner']);
            $defines = $model->params;
            unset($defines['inputformat']);
            unset($defines['outputformat']);
            unset($defines['partitioner']);
            $params->other_define = implode("\r\n", $defines); 
            $model->params = $params;
        }

        $this->decodeInputs($model);
        $this->decodeOutputs($model);
        
    	if(isset($_POST['Activity']))
    	{
    		$model->setAttributes($_POST['Activity'], false);
	    	if($model->activity_type != ActivityType::MapRed) {
	            $model->programs=CJSON::encode(array($_POST['Activity']['programs']));
	        }
	        else {
	        	$status = $this->createMapRedActivity($model);
	        	if($status == false) {
	        		Yii::log("update mapred activity[{$model->activity_name}] failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
	        		return false;
	        	}
	        }
	        
    		if($model->save()) {
    			$this->redirect(array('index', 'type'=>$model->activity_type));
    		}
    		else {
    			Yii::log("save activity[{$model->activity_name}] to DB failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
    		}
    	}
    	
        $this->render('create',array(
            'model'=>$model,
            'type' =>$type,
        ));
    }

    public function actionAddInput() {
        $inputForm=new InputForm;
        $inputForm->partition = '{0, 1 day}'; 
        $inputForm->input_type = ResourceType::Log;
        Yii::app()->clientScript->scriptMap['jquery.js'] = false;
        $this->renderPartial('_mrinput',array('model'=>$inputForm,),false,true);
    }

    public function actionGetInput() {

        $input_type = $_POST['input_type'];
        $resources = Resource::model()->findAllByAttributes(array('res_type'=>$input_type));
        $resources =  CHtml::listData($resources, 'res_id', 'res_name'); 
        foreach($resources as $key=>$value)
        {
            echo CHtml::tag('option',array('value'=>$key), CHtml::encode($value),true);
        }
    }

    public function actionDelete() 
    {
        if(Yii::app()->request->isPostRequest)
        {
            $model = $this->loadModel();
            $status = $model->delete();
            if($status) {
                Yii::log("activity[{$_GET['id']}] was deleted successfully", CLogger::LEVEL_INFO, FRONTEND_LOG);
            }
            else {
                Yii::log("activity[{$_GET['id']}] was deleted failed", CLogger::LEVEL_ERROR, FRONTEND_LOG);
            }
            if(!isset($_GET['ajax'])) {
                $this->redirect(array('index'));
            }
        }
        else {
            throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
        }
    }
    
    public function actionCheckOutput() {
        if(empty($_POST['OutputForm']['output_name'])) {
            echo '请填写输出名';
            Yii::app()->end();
        }

        $resource = Resource::model()->findByAttributes(array('res_name' => $_POST['OutputForm']['output_name']));
        if(isset($resource)) {
            echo '输出名 ['. $_POST['OutputForm']['output_name'] . '] 已经被采用';
        }
        else {
            echo '恭喜你！输出名 ['. $_POST['OutputForm']['output_name'] . '] 可以使用';
        }
        Yii::app()->end();
    }

    private function decodeInputs($model) {
    	// parse inputs
        $model->inputs = CJSON::decode($model->inputs);
        if(is_array($model->inputs)) {
            $inputs = array();
            foreach($model->inputs as $input) {
                $inputForm = new InputForm;
                $inputForm->depend_type = $input['depend_type'];
                $inputForm->input_type = $input['input_type'];
                $inputForm->partition = $input['partition'];
                $inputForm->log_pattern = $input['log_pattern'];
                $inputForm->res_id = $input['resource']['res_id'];
                $inputs[] = $inputForm;
            }
            $model->inputs = $inputs;
        }
    }
    
    private function decodeOutputs($model) {
    	// parse outputs
        $model->outputs = CJSON::decode($model->outputs);
        if(is_array($model->outputs)) {
            $outputs = array();
            foreach($model->outputs as $output) {
                $outputForm = new OutputForm;
                $outputForm->output_name = $output['resource']['res_name'];
                $outputForm->output_desc = $output['resource']['res_desc'];
                $outputForm->output_multiple = $output['multiple'];
                $outputForm->output_freq = $output['resource']['res_frequency'];
                $outputs[] = $outputForm;
            }
            $model->outputs = $outputs;	
        }
    }
    
    private function encodeInputs($model) {
    	if(empty($_POST['OutputForm']['output_name'])) {
            return true;
        }
        
    	$i = 0;
    	$inputs = array();
    	$resService = ResourceService::getInstance();
    	foreach ($_POST['depend_type'] as $depend_type) {
    		$input = array(
		        'depend_type'	=>	$depend_type,
		        'input_type'	=>	$_POST['input_type'][$i],
		        'resource'		=>	$resService->getResourceById($_POST['res_id'][$i]),
		        'partition'		=>	$_POST['partition'][$i],
		        'log_pattern'	=>	$_POST['log_pattern'][$i],
    		);
    		$inputs[$i++] = $input;
    	}
    	$model->inputs = CJSON::encode($inputs);	
    }
    
    private function encodeOutputs($model) {
        if(empty($_POST['OutputForm']['output_name'])) {
            return true;
        }
        
    	if($model->isNewRecord) {
    		$tmpResource = Resource::model()->findByAttributes(array(
    			'res_name'	=>	$_POST['OutputForm']['output_name'],
    		));
			if(isset($tmpResource)) {
				$this->alert("输出名 [{$_POST['OutputForm']['output_name']}] 已经被采用，请更换。");
			}
			return false;
    	}
        
    	$resService = ResourceService::getInstance();
    	$outputResource = array(
    		'res_name'  =>  $_POST['OutputForm']['output_name'],
			'product_id'    =>  1,
			'res_type'  =>  ResourceType::ComputeOutput,
			'res_frequency' =>  $_POST['OutputForm']['output_freq'],
			'quality_level' =>  QualityLevel::OfflineRoutine,
            'res_desc'  =>  $_POST['OutputForm']['output_desc'],
    	);
    	$outputResId = $resService->addOutputResource($outputResource);
    	if($outputResId === false) {
    		Yii::log("can't add output resource for [{$_POST['OutputForm']['output_name']}]", CLogger::LEVEL_ERROR, FRONTEND_LOG);
    		return false;
    	}
    	$outputResource['res_id'] = $outputResId;
    	$outputs = array(array('resource'=>$outputResource, 'multiple'=>$_POST['OutputForm']['output_multiple']));
    	$model->outputs = CJSON::encode($outputs);
    	return true;
    }
    
    private function createActivity($model) {
    	$model->programs = CJSON::encode(array($_POST['Activity']['programs']));
    	$this->encodeInputs($model);
		return $this->encodeOutputs($model); 
    }
    
    private function createMapRedActivity($model)
    {
    	if($_POST['Activity']['mapred_type'] == MapRedType::Native) {
    		$model->programs = CJSON::encode(array($_POST['Activity']['jar']));
    	}
    	else {
    		$model->map = $_POST['Activity']['map'];
    		$model->reduce = $_POST['Activity']['reduce'];
    		$model->programs=CJSON::encode(array($model->map, $model->reduce));
    	}
	
        // handle params
        $params = explode("\r\n", trim($_POST['ParamForm']['other_define']));
        
        if(!empty($_POST['ParamForm']['input_format'])) {
            $params['inputformat'] = '-inputformat '. $_POST['ParamForm']['input_format'];
        }
        if(!empty($_POST['ParamForm']['output_format'])) {
            $params['outputformat'] = '-outputformat '. $_POST['ParamForm']['output_format'];
        }
        if(!empty($_POST['ParamForm']['partitioner'])) {
            $params['partitioner'] = '-partitioner ' . $_POST['ParamForm']['partitioner'];
        }
    	$model->params = CJSON::encode($params);
    	
    	$this->encodeInputs($model);
		if(!$this->encodeOutputs($model)) {
			return false;
		}
    	return true;
    }

    private function loadModel()
    {
        if($this->_model===null)
        {
            if(isset($_GET['id']))
            {
                $this->_model=Activity::model()->findByPk($_GET['id']);
            }
            if($this->_model===null)
            {
                throw new CHttpException(404,'The requested page does not exist.');
            }
        }
        return $this->_model;
    }
}
